package com.yingsheng.bi.hks.web.component;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpMethod;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

@Slf4j
public class HttpRequestWrapper extends ContentCachingRequestWrapper {

    private HttpServletRequest request;

    public HttpRequestWrapper(HttpServletRequest request) {
        super(request);
        this.request = request;
    }

    public String getReqBodyString() throws IOException {
        byte[] httpBoydByte = getReqBody();
        String httpReqBodyString = new String(httpBoydByte, super.getCharacterEncoding());
        return httpReqBodyString;
    }

    public byte[] getReqBody() throws IOException {
        if (!ObjectUtils.isEmpty(super.getContentAsByteArray())) {
            return super.getContentAsByteArray();
        }
        if (isFormPost(this.request)) {
            super.getParameterMap();
        } else {
            IOUtils.toByteArray(super.getInputStream());
        }
        return super.getContentAsByteArray();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        byte[] httpBodyByte = super.getContentAsByteArray();
        final ByteArrayInputStream bis = new ByteArrayInputStream(httpBodyByte);
        ServletInputStream sis = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() throws IOException {
                return bis.read();
            }
        };
        return sis;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    private static boolean isFormPost(HttpServletRequest request) {
        String contentType = request.getContentType();
        return contentType != null && contentType.contains("application/x-www-form-urlencoded") && HttpMethod.POST.matches(request.getMethod());
    }
}
